package logic;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;

import util.Util;

public class CircleObject extends GameObject {
	
	protected float rad = 30.0f;
	
	public float getRad() {
		return rad;
	}

	public void setRad(float rad) {
		this.rad = rad;
	}

	public CircleObject(float x, float y, float rad)
	{
		pos._set(x, y);
		this.rad = rad;
	}

	@Override
	public void draw(Graphics2D g) {
		g.setColor(color);
		g.fillOval((int)(pos.x - rad), (int)(pos.y - rad), (int)(rad * 2), (int)(rad * 2));
		g.setColor(Color.black);
		g.drawOval((int)(pos.x - rad), (int)(pos.y - rad), (int)(rad * 2), (int)(rad * 2));
	}

	@Override
	public void checkBounds(float x1, float y1, float x2, float y2, float bounce) {
		if(pos.x + rad > x2)
		{
			pos.x = (float) (x2 - rad);
			if(dir.x > 0.0f) dir.x *= -1;
			dir._mul(bounce);
		}
		if(pos.y + rad > y2)
		{
			pos.y = (float) (y2 - rad);
			if(dir.y > 0.0f) dir.y *= -1;
			dir._mul(bounce);
		}
		if(pos.x - rad < x1)
		{
			pos.x = x1 + rad;
			if(dir.x < 0.0f) dir.x *= -1;
			dir._mul(bounce);
		}
		if(pos.y - rad < y1)
		{
			pos.y = y1 + rad;
			if(dir.y < 0.0f) dir.y *= -1;
			dir._mul(bounce);
		}
	}

	@Override
	public Vec2D collisionWith(GameObject obj) {
		if(!(obj instanceof CircleObject))
			return null;
		
		CircleObject o = (CircleObject)obj;
		
		if(pos.distanceTo(o.pos) <= rad + o.rad)
		{
			float x = rad / (rad + o.rad);
			return Util.lerp(pos, o.pos, x);
			//return Util.lerp(pos, o.pos, 0.5f);
		}
		return null;
	}

	@Override
	public void backtrack(Vec2D col) {
		Vec2D back1 = pos.sub(col);
		float dist = back1.getLength();
		back1.normalize();
		back1 = back1.mul(rad - dist);
		pos = pos.add(back1);
		//dir._set(0, 0);
	}
	
	public static boolean collideCircles(CircleObject a, CircleObject b)
	{
		// separation vector
		Vec2D d = new Vec2D(b.pos.sub(a.pos));
		float distance_squared = d.dot(d);
		float radius = b.rad + a.rad;
		float radius_squared = radius * radius;
		
		// circles apart
		if(distance_squared > radius_squared)
			return false;
		
		float distance = (float) Math.sqrt(distance_squared);
		// normal of collision
		Vec2D ncoll = (d.div(distance));
		
		// penetration distance
		float dcoll = radius - distance;
		
		float ima = a.recMass;
		float imb = b.recMass;
		
		// separation vector
		Vec2D separation_vector = ncoll.mul(dcoll / (ima + imb));
		
		// separate
		a.pos._add(separation_vector.mul(ima * 1.1f));
		b.pos._add(separation_vector.mul(imb * 1.1f));
		
		// combine velocity
		Vec2D vcoll = b.dir.sub(a.dir);
		
		// impact speed
		float vn = vcoll.dot(ncoll);
		
		//if(vn > 0.0f)
			//return
		final float cor = 0.95f;
		
		// collision impulse
		float j = -(1.0f + cor) * vn / (ima + imb);
		
		// collision impulse vector
		Vec2D impulse = ncoll.mul(j);
		
		a.dir._add(impulse.mul(-ima));
		b.dir._add(impulse.mul(imb));
		
		return true;
	}
	
}
